package com.msh.frame.common.util;

import com.msh.frame.client.base.IConvert;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class CollectionUtil {

  /**
   * 拆分集合变动信息
   * 例:
   * 数据库有 A,B,C三条数据，
   * 更新后数据为 B,C,D 三条数据，
   * 处理后:
   * save 结果为  D
   * del 结果为 A
   * @param before 之前集合
   * @param change 修改后的集合
   * @param save 需要保存的集合 传入空集合
   * @param del 需要删除的集合 传入空集合
   * @param <T>
   */
  public static <T> void split(Collection<T> before, Collection<T> change, Collection<T> save, Collection<T> del){
    if(isEmpty(before) && isEmpty(change)){
      return;
    }
    if(isEmpty(before)){
      save.addAll(change);
      return;
    }
    if(isEmpty(change)){
      del.addAll(before);
      return;
    }
    List<T> noChangeList = before.stream().filter(b -> change.contains(b))
        .collect(Collectors.toList());
    before.stream().filter(b -> !noChangeList.contains(b)).forEach(b->{
      del.add(b);
    });
    change.stream().filter(b -> !noChangeList.contains(b)).forEach(c->{
      save.add(c);
    });
  }

  private static boolean isEmpty(Collection c){
    if(null ==c || 0 == c.size()){
      return true;
    }
    return false;
  }

  /**
   * 转换列表
   * @param s
   * @param tClazz
   * @param <ScouceT> 源类信息
   * @param <TargetT> 转换后类信息
   * @return
   */
  public static <ScouceT extends IConvert, TargetT extends IConvert> List<TargetT> convertList(
      List<ScouceT> s, Class<TargetT> tClazz) {
    return s.stream()
        .map(o -> o.convert(tClazz))
        .collect(Collectors.toList());
  }

  /**
   * map 放入值
   * @param map key  list<value> 对象
   * @param k
   * @param vs
   * @param <K>
   * @param <V>
   */
  public static <K, V> void putList(Map<K, List<V>> map, K k, V... vs) {
    List<V> list = map.get(k);
    if (null == list) {
      list = new LinkedList<V>();
      map.put(k, list);
    }
    for (V v : vs) {
      list.add(v);
    }
  }

  /**
   * map 放入值
   * @param map key  Set<value>
   * @param k
   * @param vs
   * @param <K>
   * @param <V>
   */
  public static <K, V> void putSet(Map<K, Set<V>> map, K k, V... vs) {
    Set<V> set = map.get(k);
    if (null == set) {
      set = new HashSet<>();
      map.put(k, set);
    }
    for (V v : vs) {
      set.add(v);
    }
  }
}
